package tianrun.ziguan.api.calculate.config.service.asset.module.impl;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import tianrun.ziguan.api.calculate.config.dao.TAssetStaticPropertiesModuleMapper;
import tianrun.ziguan.api.calculate.config.dto.request.AssetStaticPropertiesInstanceVO;
import tianrun.ziguan.api.calculate.config.dto.request.BusinessParam;
import tianrun.ziguan.api.calculate.config.dto.request.UpdateStaticPropertiesParam;
import tianrun.ziguan.api.calculate.config.entity.TAssetGroup;
import tianrun.ziguan.api.calculate.config.entity.TAssetStaticPropertiesInstance;
import tianrun.ziguan.api.calculate.config.entity.TAssetStaticPropertiesModule;
import tianrun.ziguan.api.calculate.config.entity.TCalAsset;
import tianrun.ziguan.api.calculate.config.service.asset.group.ITAssetGroupService;
import tianrun.ziguan.api.calculate.config.service.asset.instance.ITAssetStaticPropertiesInstanceService;
import tianrun.ziguan.api.calculate.config.service.asset.module.ITAssetStaticPropertiesModuleService;
import tianrun.ziguan.api.calculate.config.service.business.RefreshCacheService;
import tianrun.ziguan.api.calculate.config.service.cal.asset.ITCalAssetService;
import tianrun.ziguan.api.calculate.config.utils.CollectionUtil;
import tianrun.ziguan.api.common.util.ListUtil;
import tianrun.ziguan.api.common.util.SpringContextUtil;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class TAssetStaticPropertiesModuleServiceImpl extends ServiceImpl<TAssetStaticPropertiesModuleMapper, TAssetStaticPropertiesModule> implements ITAssetStaticPropertiesModuleService {
    private final ITAssetStaticPropertiesInstanceService assetStaticPropertiesInstanceService;
    private final ITCalAssetService calAssetService;
    private static final Logger log = LoggerFactory.getLogger(TAssetStaticPropertiesModuleServiceImpl.class);

    public TAssetStaticPropertiesModuleServiceImpl(ITAssetStaticPropertiesInstanceService assetStaticPropertiesInstanceService, ITCalAssetService calAssetService) {
        this.assetStaticPropertiesInstanceService = assetStaticPropertiesInstanceService;
        this.calAssetService = calAssetService;
    }

    @Override
    public List<TAssetStaticPropertiesModule> getByCalAssetIds(Set<Long> calAssetIds) {
        if (CollectionUtil.isEmpty(calAssetIds)) return Collections.emptyList();
        return list(Wrappers.<TAssetStaticPropertiesModule>lambdaQuery().in(TAssetStaticPropertiesModule::getCalAssetId, calAssetIds));
    }

    @Override
    public void updateValueByLabel(List<UpdateStaticPropertiesParam> params) {
        Set<String> assetNums = params.stream().map(UpdateStaticPropertiesParam::getAssetNum).collect(Collectors.toSet());
        List<AssetStaticPropertiesInstanceVO> assetStaticPropertiesInstanceVOS = assetStaticPropertiesInstanceService.listVOByAssetNums(assetNums);
        Map<String, List<AssetStaticPropertiesInstanceVO>> instancesMap = ListUtil.groupList(assetStaticPropertiesInstanceVOS, AssetStaticPropertiesInstanceVO::getAssetNum);

        ArrayList<TAssetStaticPropertiesInstance> updates = Lists.newArrayList();
        ArrayList<TAssetStaticPropertiesInstance> inserts = Lists.newArrayList();
        HashSet<Long> groupIds = Sets.newHashSet();
        params.forEach(param -> {
            List<UpdateStaticPropertiesParam.DataItem> data = param.getData();
            if (CollectionUtil.isEmpty(data)) return;
            String assetNum = param.getAssetNum();
            TCalAsset asset = calAssetService.getByAssetNum(assetNum);
            if (asset == null) {
                log.warn("没有该资产编号:{}",assetNum);
                return;
            }
            groupIds.add(asset.getAssetGroupId());
            List<AssetStaticPropertiesInstanceVO> instanceVOS = instancesMap.getOrDefault(assetNum, Collections.emptyList());
            Long moduleId = null;

            if (CollectionUtil.isEmpty(instanceVOS)) {
                //需要新增
                //查找设备下的组件
                moduleId = getModuleId(asset);
                if (Objects.isNull(moduleId))return;
            }

            //修改
            Map<String, AssetStaticPropertiesInstanceVO> instanceLabelMap = ListUtil.toMap(instanceVOS, TAssetStaticPropertiesInstance::getLabel, Function.identity());
            for (UpdateStaticPropertiesParam.DataItem dataItem : data) {
                String label = dataItem.getLabel();
                String value = dataItem.getValue();
                if (StringUtils.isEmpty(label) || StringUtils.isEmpty(value)) continue;
                AssetStaticPropertiesInstanceVO assetStaticPropertiesInstanceVO = instanceLabelMap.get(label);
                if (assetStaticPropertiesInstanceVO == null) {
                    if (Objects.isNull(moduleId)) {
                        moduleId = getModuleId(asset);
                        if (Objects.isNull(moduleId))return;
                    }
                    //需要新增
                    TAssetStaticPropertiesInstance insert = new TAssetStaticPropertiesInstance();
                    insert.setLabel(label);
                    insert.setValue(value);
                    insert.setModuleId(moduleId);
                    insert.setTemplateInstanceId(-1L);
                    inserts.add(insert);
                } else {
                    TAssetStaticPropertiesInstance update = new TAssetStaticPropertiesInstance();
                    update.setValue(value);
                    update.setId(assetStaticPropertiesInstanceVO.getId());
                    updates.add(update);
                }
            }
        });
        if (!inserts.isEmpty())
            assetStaticPropertiesInstanceService.saveBatch(inserts);
        if (!updates.isEmpty())
            assetStaticPropertiesInstanceService.updateBatchById(updates);
        //刷新静态缓存
        List<TAssetGroup> assetGroups = SpringContextUtil.getBean(ITAssetGroupService.class).getByIds(groupIds);
        RefreshCacheService refreshCacheService = SpringContextUtil.getBean(RefreshCacheService.class);
        assetGroups.forEach(tAssetGroup -> {
            new Thread(() -> {
                String deptNum = tAssetGroup.getName();
                refreshCacheService.refreshStaticModule( BusinessParam.of(deptNum));
                refreshCacheService.informToCalculate(Lists.newArrayList(deptNum));
            }).start();
        });
    }

    private Long getModuleId(TCalAsset asset) {
        Long moduleId;

        List<TAssetStaticPropertiesModule> modules = getByCalAssetIds(Sets.newHashSet(asset.getId()));
        String moduleName = "静态值(导入)";
        Optional<TAssetStaticPropertiesModule> module = modules.stream().filter(m -> Objects.equals(m.getName(), moduleName)).findFirst();
        if (!module.isPresent()) {
            //新增组件
            TAssetStaticPropertiesModule insertModule = new TAssetStaticPropertiesModule();
            insertModule.setCalAssetId(asset.getId());
            insertModule.setName(moduleName);
            insertModule.setTemplateModuleId(-1L);
            save(insertModule);
            moduleId = insertModule.getId();
        } else moduleId = module.get().getId();
        return moduleId;
    }
}
